/*本文件实现了OSD区域内存管理。
*OSD_mem_create创建了一个大的链表，该链表内部包含了需要管理地址（大内存）的起始地址和大小以及一个待使用的busylist链表
*OSD_mem_alloc实现了内存结点的创建以及内存整理的工作。如下所示，
————————————————————————————————————————————————————————
|  0  |   1  |    2   |   3   |  4  |       remain     |
————————————————————————————————————————————————————————
*1、当用户申请的区域大小小于remain时，直接新建一个节点，指向remain起始地址，大小为用户指定的size。
*2、若用户释放图中1结点（标志为未使用，实际未删除），申请了新的内存,由结点5管理，而新内存大于remain小于1节点内存+remain
*   这时需要进行内存整理，即将1后所有内存向前拷贝偏移，偏移完成后删除1节点。最终得到如下的新的链表的地址结构
————————————————————————————————————————————————————————
|  0  |    2   |   3   |  4  |              remain     |
————————————————————————————————————————————————————————
*3、这时直接创建一个5结点，地址指向remain起始地址即可完成内存整理创建
————————————————————————————————————————————————————————
|  0  |    2   |   3   |  4  |         5        |remain|
————————————————————————————————————————————————————————
*
*OSD_mem_free主要完成了结点标志的释放
*/
#include "osd_mem.h"
#include <imp/imp_log.h>

#define TAG	 "OSD_MEM"

int mem_node_del(mem_node_t* pnode)
{
    if (NULL == pnode->priv) {
        pnode->list->head = pnode->next;
    } else {
        pnode->priv->next = pnode->next;
    }
    if (NULL == pnode->next) {
        pnode->list->tail = pnode->priv;
    } else {
        pnode->next->priv = pnode->priv;
    }
    return 0;
}

int mem_node_insert(mem_node_t* pn, mem_node_t* insert)
{
    if (NULL == pn->priv) {
        pn->list->head = insert;
        insert->next = pn;
        pn->priv = insert;
        insert->priv = NULL;
    } else {
        pn->priv->next = insert;
        insert->next = pn;
        insert->priv = pn->priv;
        pn->priv = insert;
    }
    insert->list = pn->list;
    return 0;
}

int mem_node_add_busy(mem_list_t* list, mem_node_t* pnode)
{
    pnode->busedflag = TRUE;

    if (list->tail) {
        pnode->next = NULL;
        pnode->priv = list->tail;
        list->tail->next = pnode;
        list->tail = pnode;
    } else {
        list->tail = pnode;
        list->head = pnode;
        pnode->priv = NULL;
        pnode->next = NULL;
    }
    pnode->list = list;
    return 0;
}

int mem_node_add_free(mem_list_t* list, mem_node_t* pnode)
{
    mem_node_t* pn = list->head;
    if (NULL == list->head) {
        list->head = pnode;
        list->tail = pnode;
        pnode->priv = NULL;
        pnode->next = NULL;
    } else {
        while (pn) {
            if (pnode->addr < pn->addr) {
                break;
            }
            pn = pn->next;
        }
        if (NULL == pn) {
            //tail
            if ((list->tail->addr+list->tail->size) == pnode->addr) {
                list->tail->size += pnode->size;
                free(pnode);
            } else {
                list->tail->next = pnode;
                pnode->priv = list->tail;
                pnode->next = NULL;
                list->tail = pnode;
            }
        } else {
            mem_node_t* ahead;
            ahead = pn->priv;
            int merge = 0;
            if ((pnode->addr+pnode->size) == pn->addr) {
                pn->size += pnode->size;
                pn->addr = pnode->addr;
                merge = 1;
            }
            if (NULL != ahead) {
                if (merge) {
                    if ((ahead->addr+ahead->size) == pn->addr) {
                        pn->addr = ahead->addr;
                        pn->size += ahead->size;
                        merge = 3;
                        //del ahead;
                        mem_node_del(ahead);
                        free(ahead);
                    }
                } else {
                    if ((ahead->addr+ahead->size) == pnode->addr) {
                        ahead->size += pnode->size;
                        merge = 2;
                    }
                }
            }
            if (0 == merge) {
                //insert
                mem_node_insert(pn, pnode);

            } else {
                free(pnode);
            }
        }
    }
    return 0;
}

mem_alloc_info_t* OSD_mem_create(void* start_addr, int32_t size)
{
	mem_alloc_info_t *mem = NULL;
    mem = malloc(sizeof(mem_alloc_info_t));
    if (NULL == mem) {
        IMP_LOG_ERR(TAG,"%s,%d: malloc failed!\n", __func__, __LINE__);
        return NULL;
    }
    memset(mem, 0, sizeof(mem_alloc_info_t));
    mem->start_addr = start_addr;
    mem->total_size = size;
    mem->busy.meminfo = mem;

    return mem;
}

int OSD_mem_destroy(mem_alloc_info_t *mem)
{
	if(NULL == mem){
		IMP_LOG_ERR(TAG,"%s,%d: OSD_mem_destroy failed!\n", __func__, __LINE__);
		return -1;
	}

	memset(mem, 0, sizeof(mem_alloc_info_t));
	free(mem);
	mem = NULL;
	return 0;
}

mem_node_t* OSD_mem_busyfirst_unusednode(mem_list_t* list)
{
	/*如果没有找到，则返回异常，告诉上一层没找到*/
	mem_node_t* pnode = NULL;
	pnode = list->head;
	int bfind = 0;
	while(pnode) {
		if (!pnode->busedflag) {
			bfind = 1;
			break;
		}
		pnode = pnode->next;
	}

    return (bfind == 1 ? pnode : NULL);
}

void OSD_mem_del_unusednode(mem_list_t* list)
{
	/*做地址整理，偏移操作*/
	void * paddr = NULL;
	mem_node_t *pnode = NULL;
	mem_node_t *pn = NULL;
	pnode = OSD_mem_busyfirst_unusednode(list);
	if(NULL == pnode){
		IMP_LOG_ERR(TAG,"[%s][%d]err!!not find first unusednode\n", __func__, __LINE__);
		return ;
	}
	/*找到一个空闲节点， 然后将其后面的所有结点都做地址偏移*/
	paddr = pnode->addr;
	while (pnode) {
		pn = pnode->next;
		if(pn) {
            pnode->list->meminfo->brmemsetbak = 1;
			memcpy(paddr, pn->addr, pn->size);
			pn->addr = paddr;//pn的地址=pnode的地址, 空闲节点后的新节点地址
			paddr = pn->addr + pn->size; //这个地址指向下一次要拷贝的目的地址处。

		}else {
			//尾结点地址不做处理了
		}
		pnode = pnode->next;
	}

	/*要从链表里删除这个结点*/
	pnode = OSD_mem_busyfirst_unusednode(list);
	if(NULL == pnode){
		IMP_LOG_ERR(TAG,"[%s][%d]err!!not find first unusednode\n", __func__, __LINE__);
	} else{
		mem_node_del(pnode);
		free(pnode);
		pnode = NULL;
	}
	return ;
	/*以上操作完成了将一个未使用的节点内存整理释放的过程，但是如何保证多个未使用的节点呢？,上层重复调用*/

}

void* OSD_mem_alloc(mem_alloc_info_t* minfo, int32_t size)
{
	/*需要我这在这里进行整理内存的操作*/
	//mem_alloc_info_t* minfo = osd->osd_mem;
    //printf("[%s][%d]OSD_mem_alloc start run,size=%d\n", __func__, __LINE__,size);

    void* addr = 0;
    mem_node_t* pnode = minfo->busy.head; /*计划只用一个链表*/
    mem_node_t* pn = NULL;
    if ((size&(~0x3)) != size) {
        IMP_LOG_ERR(TAG,"%s,%d: alloc size need 4 bypts aligned\n", __func__, __LINE__);
        return NULL;
    }

	int32_t s32node_usesize = 0,s32node_unusedsize = 0,s32node_totalsize = 0;
	int32_t s32remainsize = 0;
    s32remainsize = minfo->total_size;
	/*头结点为空的情况,创建一个头结点*/
	if(NULL == pnode){
		if(size <= s32remainsize) {
			pn = malloc(sizeof(mem_node_t));
			if (NULL == pn) {
				IMP_LOG_ERR(TAG,"[%s][%d]: malloc failed!\n", __func__, __LINE__);
				return 0;
			}
			memset(pn, 0, sizeof(mem_node_t));
			pn->addr = minfo->start_addr;
			pn->oldaddr = pn->addr;
	        pn->size = size;
			mem_node_add_busy(&minfo->busy, pn);
			addr = pn->addr;
			s32remainsize -= size;
            //printf("first pnode->busedflag=%d\n",minfo->busy.head->busedflag);
			return addr;
		} else {
			//IMP_LOG_ERR(TAG,"[%s][%d]err!!not enough space，size=%d\n", __func__, __LINE__,size);
			IMP_LOG_ERR(TAG,"[%s][%d]err!!not enough space,size=%d,remainsize:%d,total_size:%d\n", __func__, __LINE__,size,s32remainsize,minfo->total_size);
			return NULL;
		}
	}

	/*应该先查询busy链表中剩余空间大小，并记录当前所有结点的地址信息*/
	while (pnode) {
		if (pnode->busedflag) {
			s32node_usesize += pnode->size;
		} else {
			s32node_unusedsize += pnode->size;
		}
		s32node_totalsize += pnode->size; /*统计使用大小，包括使用和未使用的*/
		s32remainsize = minfo->total_size - s32node_totalsize;/*剩余尾部大小*/
		pnode = pnode->next;
	}
	//IMP_LOG_ERR(TAG,"size=%d,remain=%d,unusedsize=%d,usedsize=%d,total_size=%d\n",size,s32remainsize,s32node_unusedsize,s32node_usesize,minfo->total_size);
	/*尾部有剩余空间，则直接在节点后创建*/
	if (size <= s32remainsize) {
		//addr = minfo->start_addr; //起始地址为创建的起始地址
		pn = malloc(sizeof(mem_node_t));
		if (NULL == pn) {
			IMP_LOG_ERR(TAG,"%s,%d: malloc failed!\n", __func__, __LINE__);
			return 0;
		}
		memset(pn, 0, sizeof(mem_node_t));
		pn->addr = minfo->start_addr + s32node_totalsize; //这样pnaddr始终可以指向最后的地址空间
		pn->size = size;
		addr = pn->addr;
        pn->oldaddr = addr;/*创建时刻记录oldaddr */
		mem_node_add_busy(&minfo->busy, pn);
		//IMP_LOG_ERR(TAG,"\033[0;31m %s,%d:size < remainsize addr:----%p---- \033[0m \n", __func__, __LINE__,addr );

	} else if (size <= (s32remainsize + s32node_unusedsize)) {

        pnode = minfo->busy.head;
		while (pnode) {
			if(!pnode->busedflag){
				/*查找busy里第一个空闲节点，将其后的结点内容前向拷贝，并删除该空闲结点*/
				OSD_mem_del_unusednode(&minfo->busy);
				pnode = minfo->busy.head;

                if(NULL == pnode){
                    //printf("pnode's is null\n");
                    break;
                }else if(!pnode->busedflag){
                    continue;
                }
			}
			pnode = pnode->next;
		}

		pnode = minfo->busy.head;
		s32node_usesize = 0;//重置，用于重新计算新链表下的内存使用和
		s32node_totalsize = 0;
		while (pnode) {
			if (pnode->busedflag) {
				s32node_usesize += pnode->size;
			} else {
				IMP_LOG_ERR(TAG,"[%s][%d]: if run here,it is an err,flag = %d,size=%d\n", __func__, __LINE__,pnode->busedflag,pnode->size);

			}
			s32node_totalsize += pnode->size; /*统计使用大小，包括使用和未使用的*/
			//s32remainsize = minfo->total_size - s32node_totalsize;/*剩余尾部大小*/
			pnode = pnode->next;
		}
	    //printf("s32node_usesize=%d,node_totalsize=%d\n",s32node_usesize,s32node_totalsize);

		/*偏移完成后，需要进行申请结点，并将结点内存指定*/
		pn = malloc(sizeof(mem_node_t));
		if (NULL == pn) {
			IMP_LOG_ERR(TAG,"%s,%d: malloc failed!\n", __func__, __LINE__);
			return 0;
		}
		memset(pn, 0, sizeof(mem_node_t));
		pn->addr = minfo->start_addr + s32node_totalsize; //这样pnaddr始终可以指向最后的地址空间
		pn->oldaddr = pn->addr;
		pn->size = size;
		addr = pn->addr;
		mem_node_add_busy(&minfo->busy, pn);
		//IMP_LOG_ERR(TAG,"\033[0;31m %s,%d:(size<=remainsize+node_unusedsize) addr:----%p---- \033[0m \n", __func__, __LINE__,addr );

	} else {
		//printf("\033[0;31m", "\033[1;31;40m 输出红色字符 \033[0m" "\033[0;31m");
		IMP_LOG_ERR(TAG,"\033[0;31m %s,%d:not enough space,size=%d,remain=%d,unusedsize=%d,usedsize=%d,total_size=%d \033[0m \n", __func__, __LINE__,
			size,s32remainsize,s32node_unusedsize,s32node_usesize,minfo->total_size);
		return NULL;
	}
#if 0
	mem_node_t* pdbgnode = minfo->busy.head;
	while(pdbgnode) {
		IMP_LOG_ERR(TAG,"%s,%d: ----------pdbgnode addr  %p,oldaddr %p,pdbgnode->flag:%d---\t", __func__, __LINE__,pdbgnode->addr,pdbgnode->oldaddr,pdbgnode->busedflag);
		pdbgnode = pdbgnode->next;
	}
	IMP_LOG_ERR(TAG,"\n", __func__, __LINE__);
#endif

    return addr;
}

#if 0
int32_t OSD_mem_try_alloc(mem_alloc_info_t* minfo, int32_t size)
{
    mem_node_t* pnode = minfo->free.head;
    while (pnode) {
        if (size <= pnode->size) {
            return 1;
        }
        pnode = pnode->next;
    }
    return 0;
}
#endif

int32_t OSD_mem_free(mem_alloc_info_t* minfo, void* start_addr)
{
	//printf("free start_addr:%p\n",start_addr);
    mem_node_t* pnode = minfo->busy.head;
    while (pnode) {
        if (start_addr == pnode->addr) {
            break;
        }
        pnode = pnode->next;
    }
    if (NULL == pnode) {
		IMP_LOG_ERR(TAG,"%s,%d: free mem:%p do not found!\n", __func__, __LINE__,start_addr);
        return -1;
    }
    //mem_node_del(pnode);
    /*找到相应的地址后，将该节点进行标记*/
    pnode->busedflag = FALSE;
    //mem_node_add_free(&minfo->free, pnode);
	/*若该节点的前驱或者后继是相连的，则合并，否则不处理*/
#if 1
	mem_node_t* pre = NULL;
	mem_node_t* pnext = NULL;
	pre = pnode->priv;
	pnext = pnode->next;
	if (pre && ( FALSE == pre->busedflag ) &&(pre->addr + pre->size == pnode->addr)) {
		pre->size += pnode->size;
        //printf("pre->addr +size == pnode->addr\n");
		mem_node_del(pnode);
		free(pnode);
	}
    else if (pnext && ( FALSE == pnext->busedflag ) && (pnode->addr + pnode->size == pnext->addr)) {
		pnode->size += pnext->size;
       // printf("pnode->addr+size == pnext->addr\n");
		mem_node_del(pnext);
		free((pnext));
	}
	//printf(GREEN"[%s][%d]: free succeed\n"NONE, __func__, __LINE__);
#endif
    return 0;
}


/*调试时只要这里修改即可*/
#if 0
struct test_list_s;
#define MAXTESTNUM 20
typedef struct test_list_s {
	int32_t s32Index;
    int32_t size;
    void* p;
	struct test_list_s *pre;
	struct test_list_s *next;
} TEST_NODE_T;

typedef struct list {
	TEST_NODE_T *phead;
	TEST_NODE_T *ptail;
}test_list_list;

typedef struct {
	TEST_NODE_T			rnode[MAXTESTNUM];
	test_list_list		freerlist;
	test_list_list		busyrlist;
} OSDMEME;

int32_t OSD_mem_dump(mem_alloc_info_t* minfo,OSDMEME *ptestlist)
{
    static int i = 0;
	FILE *fp = NULL;
	char str[64] = {0};
	sprintf(str,"./test_%d",i++);
	if(fp = fopen(str,"w+")){
		printf("fopen succeed\n");
	}else{
		printf(RED"fopen err!\n"NONE);
		return -1;
	}

    mem_node_t* pnode = minfo->busy.head;
    printf("--------------dump times=%d---------------------------\n",i++);
    printf("mem info: address %p, total size %x\n", minfo->start_addr, minfo->total_size);
    printf("busy list:\n");
    while (pnode) {
		if(pnode->busedflag == TRUE ){
			printf("index = %d, addr = %p, size = %x\n", pnode->s32Index, pnode->addr, pnode->size);

		} else {
			printf("check please!,pnode->idex=%d,addr=%p\n",pnode->s32Index,pnode->addr);
		}
        pnode = pnode->next;
    }

	TEST_NODE_T * ptestnode = ptestlist->busyrlist.phead;
	while(ptestnode){
		if(fwrite(ptestnode->p,1,ptestnode->size,fp) < 0){
			printf(RED"fread err!\n"NONE);
		}
		ptestnode = ptestnode->next;
	}

    return 0;
}


#if 0
/*这里暂时分配了768k，差256k到1M*/
test_list_t tl[] = {
    { 64*1024, 0},
    {128*1024, 0},
    { 64*1024, 0},
    {128*1024, 0},
    { 64*1024, 0},
    {128*1024, 0},
    { 64*1024, 0},
    {128*1024, 0},
};

int *test_free;

void osd_mem_testbackaddr(mem_alloc_info_t* osd_mem )
{
	mem_node_t* pnode = NULL;

	pnode = osd_mem->busy.head;
	int i = 0;
	while(pnode){

		for(i = 0;i < sizeof(tl)/sizeof(tl[0]);i++){
			if(pnode->oldaddr == tl[i].p){
				printf(RED" [%s]:find %d oldaddr=%p,newaddr=%p \n"NONE, __func__,i,pnode->oldaddr,pnode->addr);
				/*新旧地址不一样才应该修改，否则不需要修改*/
				tl[i].p = pnode->addr;
			}
		}
		pnode = pnode->next;
	}

	return ;
}
#endif

int test_creatRgn(OSDMEME *ptestlist,mem_alloc_info_t* meminfo,int s32size)
{
	void *pdata = NULL;
	/*2 创建一个内存结点区域*/
	pdata = OSD_mem_alloc(meminfo, s32size);
	if(NULL == pdata){
		printf(RED"[%s][%d]osd_mem_alloc err\n"NONE, __func__,__LINE__);
		return -1;
	}
	/*3、将节点加入到busylist中*/
	TEST_NODE_T * prnode = NULL;
	prnode = ptestlist->freerlist.phead;
	ptestlist->freerlist.phead = ptestlist->freerlist.phead->next;/*头往后偏移*/

	if (ptestlist->freerlist.phead == NULL) {
		ptestlist->freerlist.ptail = NULL;
	} else {
		ptestlist->freerlist.phead->pre = NULL;
	}

	if (ptestlist->busyrlist.phead == NULL) {
		ptestlist->busyrlist.phead = ptestlist->busyrlist.ptail = prnode;
		ptestlist->busyrlist.ptail->pre = NULL;
		ptestlist->busyrlist.ptail->next = NULL;
	} else {
		ptestlist->busyrlist.ptail->next = prnode;
		ptestlist->busyrlist.ptail->next->pre = ptestlist->busyrlist.ptail;
		ptestlist->busyrlist.ptail = ptestlist->busyrlist.ptail->next;
		ptestlist->busyrlist.ptail->next = NULL;
	}

	/*4、修改节点中的地址信息 234 可封装成一个创建区域的函数*/
	/*写点东西进去*/
	static int i = 0;
	memset(pdata,i,s32size);
	i++;
	prnode->p = pdata;
	prnode->size = s32size;
	/*地址整理*/
	mem_node_t * pmemnode = NULL;
	TEST_NODE_T * pnode = NULL;
	pnode = ptestlist->busyrlist.phead;
	pmemnode = meminfo->busy.head;
	while(pmemnode){
		while(pnode){
			if(pnode->p == pmemnode->oldaddr){

				pnode->p = pmemnode->addr;
				break;
			}
			pnode = pnode->next;
		}
		pmemnode = pmemnode->next;
	}

	return prnode->s32Index;
}

void test_destroyRgn(int handle,OSDMEME *ptestlist,mem_alloc_info_t* meminfo)
{
	TEST_NODE_T * prnode = NULL;

	/*应该是从busylist中剥离结点*/
	prnode = &ptestlist->rnode[handle];
	if (prnode != ptestlist->busyrlist.phead && prnode != ptestlist->busyrlist.ptail) {
		prnode->pre->next = prnode->next;
		prnode->next->pre = prnode->pre;
	} else if ((prnode == ptestlist->busyrlist.phead) && (prnode == ptestlist->busyrlist.ptail)) {
		ptestlist->busyrlist.phead = ptestlist->busyrlist.ptail = NULL;
	} else if ((prnode == ptestlist->busyrlist.phead) && (prnode != ptestlist->busyrlist.ptail)) {
		ptestlist->busyrlist.phead = ptestlist->busyrlist.phead->next;
		ptestlist->busyrlist.phead->pre = NULL;
	} else if ((prnode != ptestlist->busyrlist.phead) && (prnode == ptestlist->busyrlist.ptail)) {
		ptestlist->busyrlist.ptail = ptestlist->busyrlist.ptail->pre;
		ptestlist->busyrlist.ptail->next = NULL;
	}

	/*插入到freelist中*/
	if (ptestlist->freerlist.phead == NULL) {
		ptestlist->freerlist.phead = ptestlist->freerlist.ptail = prnode;
		ptestlist->freerlist.ptail->pre = NULL;
		ptestlist->freerlist.ptail->next = NULL;
	} else {
		ptestlist->freerlist.ptail->next = prnode;
		ptestlist->freerlist.ptail->next->pre = ptestlist->freerlist.ptail;
		ptestlist->freerlist.ptail = ptestlist->freerlist.ptail->next;
		ptestlist->freerlist.ptail->next = NULL;
	}

	OSD_mem_free(meminfo, prnode->p);

	return ;
}

int test1(void)
{
#define TEST_MEM_SIZE (1*1024)
    int i  = 0;
    int j  = 0;
    void* test_mem = malloc(TEST_MEM_SIZE);
    if (NULL == test_mem) {
        printf("test malloc error\n");
        return -1;
    }
	void * pdata = NULL;
    mem_alloc_info_t* meminfo = OSD_mem_create(test_mem, TEST_MEM_SIZE);

	#if 0
	test_free = malloc(sizeof(tl)/sizeof(tl[0])*sizeof(int));
    for (i = 0; i < sizeof(tl)/sizeof(tl[0]); i++) {
        test_free[i] = i;
    }
	#endif

	/*1、初始化一个freelist的链表*/
	OSDMEME *ptestlist = malloc(sizeof(OSDMEME));

	for (i = 0; i < MAXTESTNUM; i++) {
		ptestlist->rnode[i].s32Index = i;
		if (i == 0) {
			ptestlist->freerlist.phead = ptestlist->freerlist.ptail = &ptestlist->rnode[0];
			ptestlist->freerlist.ptail->pre = NULL;
			ptestlist->freerlist.ptail->next = NULL;
		} else {
			/*这里操作是将结点数组，整合起来，并将头尾指针归位两端*/
			ptestlist->freerlist.ptail->next = &ptestlist->rnode[i];
			ptestlist->freerlist.ptail->next->pre = ptestlist->freerlist.ptail;
			ptestlist->freerlist.ptail = ptestlist->freerlist.ptail->next;
			ptestlist->freerlist.ptail->next = NULL;
		}
	}
	int handle[8] = {0};
	for(i = 0; i < 6; i++){
		/*128*6 = 768
		768+256 = 1024*/
		handle[i] = test_creatRgn(ptestlist,meminfo,128);
	}
	OSD_mem_dump(meminfo,ptestlist);

	test_destroyRgn(handle[2],ptestlist,meminfo);
	OSD_mem_dump(meminfo,ptestlist);
	test_destroyRgn(handle[3],ptestlist,meminfo);
	OSD_mem_dump(meminfo,ptestlist);

	handle[6] = test_creatRgn(ptestlist,meminfo,512);/*384 512*/

    OSD_mem_dump(meminfo,ptestlist);


	return 0;
 #if 0
    for (j = 0; j < 1; j++) {
		#if 0
        srand(time(0));
        for (i = 0; i < sizeof(tl)/sizeof(tl[0]); i++) {
            int tmp,tmp1,tmp2;
            //swap
            tmp1 = rand()%(sizeof(tl)/sizeof(tl[0]));
            tmp2 = rand()%(sizeof(tl)/sizeof(tl[0]));
            printf("%d, %d\n",tmp1,tmp2);
            tmp = test_free[tmp1];
            test_free[tmp1] = test_free[tmp2];
            test_free[tmp2] = tmp;
        }
        printf("free order:\n");
        for (i = 0; i < sizeof(tl)/sizeof(tl[0]); i++) {
            printf("i = %d, free = %d\n",
                    i, test_free[i]);
        }
		#endif

        for (i = 0; i < sizeof(tl)/sizeof(tl[0]); i++) {
            tl[i].p = OSD_mem_alloc(meminfo, tl[i].size);
			//memset(tl[i].p,i,tl[i].size);
			//fwrite(tl[i].p,1,tl[i].size,fp1);
        }
		/*更新内存地址*/
		osd_mem_testbackaddr(meminfo);

        OSD_mem_dump(meminfo);

		#if 0
        printf("alloc information:\n");
        for (i = 0; i < sizeof(tl)/sizeof(tl[0]); i++) {
            printf("i = %d, addr = %p, size = %x\n",
                    i, tl[i].p, tl[i].size);
        }
#endif
		/*先释放2 4块*/
		OSD_mem_free(meminfo, tl[2].p);
		OSD_mem_free(meminfo, tl[4].p);
		/*再申请2 4块*/
		pdata = OSD_mem_alloc(meminfo, 384*1024);
		test_list_t* ptestlist = malloc(sizeof(test_list_t));

		tl[i++].p = pdata;
		osd_mem_testbackaddr(meminfo);
		//tl[7].p = OSD_mem_alloc(meminfo, tl[3].size);
		//osd_mem_testbackaddr(meminfo);
		for (i = 0; i < sizeof(tl)/sizeof(tl[0]); i++) {

			//fwrite(tl[i].p,1,tl[i].size,fp2);
        }

		#if 0
        for (i = sizeof(tl)/sizeof(tl[0])-1; i >= 0; i--) {
            OSD_mem_free(meminfo, tl[test_free[i]].p);
            //OSD_mem_dump(meminfo);
        }
		#endif
        OSD_mem_dump(meminfo);
    }
	#endif

}

int main(int argc, unsigned char *argv[])
{

    test1();
	return 0;
}
#endif
